home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
SciAn
/
src
/
ScianButtons.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
31KB
|
1,250 lines
/* ScianButtons.c: John R. Murray, 3-30-90
creates and deals with button objects
*/
#include "Scian.h"
#include "ScianTypes.h"
#include "ScianColors.h"
#include "ScianIDs.h"
#include "ScianMethods.h"
#include "ScianLists.h"
#include "ScianErrors.h"
#include "ScianIcons.h"
#include "ScianArrays.h"
#include "ScianButtons.h"
#include "ScianWindows.h"
#include "ScianObjWindows.h"
#include "ScianScripts.h"
#include "ScianControls.h"
#include "ScianEvents.h"
#include "ScianFontSystem.h"
#include "ScianStyle.h"
#include "ScianDraw.h"
#include "ScianTextBoxes.h"
#include "ScianObjFunctions.h"
#include "ScianSnap.h"
/* globals */
ObjPtr buttonClass; /* class of buttons */
ObjPtr iconButtonClass; /* class of icon buttons */
ObjPtr iconLabeledButtonClass; /* class of labeled icon buttons */
ObjPtr radioButtonClass; /* class of radio buttons */
ObjPtr oldRadioButtonClass; /* class of radio buttons */
ObjPtr checkBoxClass; /* class of check boxes */
ObjPtr radioGroupClass; /* class of '90.. er, um.. */
Bool inhibitSaveForUndo = false;
/* temporary defs to get something going */
/* none */
/* local constants */
#define BUTTONDEPTH 4 /* button "height"=width (pixels) of border) */
#define LABELFONTFUDGE 1 /* fudge strings up (or <0 = down) to center */
#define RADIOSPACER ((int) BUTTONFONTSIZE)
/* distance in pixels from button to text */
/* values of object variables */
#define MARKERX 0 /* value of var MARKERTYPE for mark = 'X' */
#define MARKERCHECK 1 /* value of var MARKERTYPE for mark = check */
#define MARKERBLOT 2 /* value of var MARKERTYPE for mark = dot */
#define MARKERSPLAT 3 /* value of var MARKERTYPE for mark = splat */
static ObjPtr DrawButtonObj(theButton, theButtonOwner)
ObjPtr theButton, theButtonOwner;
{
#ifdef GRAPHICS
int left, right, bottom, top;
int depth;
Bool hilight, active;
ObjPtr theLabel;
char *label;
ObjPtr theColor;
int color;
if (!Get2DIntBounds(theButton, &left, &right, &bottom, &top))
{
return NULLOBJ;
}
if (IsDrawingRestricted(left, right, bottom, top))
{
return ObjFalse;
}
hilight = GetPredicate(theButton, HIGHLIGHTED);
active = GetPredicate(theButton, ACTIVATED);
theLabel = GetVar(theButton, NAME);
if (theLabel)
{
label = GetString(theLabel);
}
else
{
label = (char *) NIL;
}
theColor = GetVar(theButton, COLOR);
if (!theColor)
{
color = UIBACKGROUND;
}
else
{
color = GetPredicate(theButton, VALUE) ? GetInt(theColor) : UIBACKGROUND;
}
if (!active)
{
BeginTranslucent();
DrawRaisedRect(left, right, bottom, top, hilight ? UIHIBACKGROUND : color);
EndTranslucent();
}
else
{
DrawRaisedRect(left, right, bottom, top, hilight ? UIHIBACKGROUND : color);
}
if (label)
{
if (active)
SetUIColor(UITEXT);
else
SetUIColor(UIGREYTEXT);
SetUIFont(BUTTONFONT);
DrawAString(CENTERALIGN, (left + right) / 2,
(top+bottom)/2 + LABELFONTFUDGE - ((int) BUTTONFONTSIZE/2),
label);
}
return ObjTrue;
#endif /* GRAPHICS */
}
ObjPtr NewIconButton(left, right, bottom, top, icon, color, name, style)
int left, right, bottom, top;
int icon, color;
char *name;
int style;
/*Makes a new icon button with bounds left, right, bottom, top,
with icon icon, and color color when on (otherwise drawn in UITEXT) */
{
ObjPtr retVal;
ObjPtr iconPtr;
ObjPtr hilightPtr;
retVal = NewObject(iconButtonClass, 0);
iconPtr = NewInt(icon);
SetVar(retVal, WHICHICON, iconPtr);
Set2DIntBounds(retVal, left, right, bottom, top);
hilightPtr = ObjFalse;
SetVar(retVal, HIGHLIGHTED, hilightPtr);
SetVar(retVal, VALUE, NewInt(0));
SetVar(retVal, COLOR, NewInt(color));
SetVar(retVal, ACTIVATED, ObjTrue);
if (style != BS_PLAIN && style != BS_PITTED)
{
ReportError("NewIconButton", "Illegal button style");
SetVar(retVal, STYLE, NewInt(BS_PLAIN));
}
else
{
SetVar(retVal, STYLE, NewInt(style));
}
if (name)
{
SetVar(retVal, NAME, NewString(name));
}
return retVal;
}
/* DRAW method for icon buttons */
ObjPtr DrawIconButtonObj(theButton, theButtonOwner)
ObjPtr theButton, theButtonOwner;
{
#ifdef GRAPHICS
int left, right, bottom, top;
int depth;
Bool hilight, active;
ObjPtr theIcon;
int label;
ObjPtr boundsArray;
real bounds[4];
char buttonLabel[128];
int value;
ObjPtr theColor;
int color;
int style;
FuncTyp extraDraw;
int diFlags;
if (!Get2DIntBounds(theButton, &left, &right, &bottom, &top))
{
return NULLOBJ;
}
if (IsDrawingRestricted(left, right, bottom, top))
{
return ObjFalse;
}
hilight = GetPredicate(theButton, HIGHLIGHTED);
active = GetPredicate(theButton, ACTIVATED);
value = GetPredicate(theButton, VALUE);
style = GetInt(GetIntVar("DrawIconButtonObj", theButton, STYLE));
color = UIGREEN;
diFlags = active ? DI_DRAWFORE | DI_DRAWBACK | DI_SMALLTEXT
: DI_DRAWFORE | DI_DRAWBACK | DI_SMALLTEXT | DI_GREY;
if (value)
{
if (GetVar(theButton, COLOR))
{
color = GetInt(GetIntVar("DrawIconButtonObj" ,theButton, COLOR));
}
/* if no COLOR, color remains UIGREEN */
}
else if (hilight)
{
color = UIHIBACKGROUND;
}
else
{
switch(style)
{
case BS_PLAIN:
color = UIBACKGROUND;
break;
case BS_PITTED:
color = UIICONBACK;
break;
default:
ReportError("DrawIconButtonObj", "Illegal STYLE");
}
}
if (style == BS_PLAIN)
{
if (!active) BeginTranslucent();
DrawRaisedRect(left, right, bottom, top,
hilight ? UIHIBACKGROUND : UIBACKGROUND);
if (!active) EndTranslucent();
}
DrawIcon((left + right) / 2, (top + bottom) / 2,
GetInt(GetIntVar("DrawIconButtonObj", theButton, WHICHICON)),
(char *) NIL, (char *) NIL, color, diFlags);
if (active)
{
extraDraw = GetMethod(theButton, ICONEXTRADRAW);
if (extraDraw)
{
(* extraDraw) (theButton, (int) ((left + right) / 2), (int) ((top + bottom) / 2));
}
}
return ObjTrue;
#endif /* GRAPHICS */
}
ObjPtr NewIconLabeledButton(left, right, bottom, top, icon, color, name, style)
int left, right, bottom, top;
int icon, color;
char *name;
int style;
/*Makes a new icon button with bounds left, right, bottom, top,
with icon icon, color color when on (otherwise drawn in UITEXT)
and label name (name is also the name of the object) */
{
ObjPtr retVal;
ObjPtr iconPtr, hilightPtr;
retVal = NewObject(iconLabeledButtonClass, 0);
Set2DIntBounds(retVal, left, right, bottom, top);
iconPtr = NewInt(icon);
SetVar(retVal, WHICHICON, iconPtr);
hilightPtr = ObjFalse;
SetVar(retVal, HIGHLIGHTED, hilightPtr);
SetVar(retVal, VALUE, NewInt(0));
SetVar(retVal, ACTIVATED, ObjTrue);
SetVar(retVal, COLOR, NewInt(color));
if (style != BS_PLAIN && style != BS_PITTED)
{
ReportError("NewIconLabelledButton", "Illegal button style");
SetVar(retVal, STYLE, NewInt(BS_PLAIN));
}
else
{
SetVar(retVal, STYLE, NewInt(style));
}
if (name)
{
SetVar(retVal, NAME, NewString(name));
SetVar(retVal, LABEL, NewString(name));
}
else
{
SetVar(retVal, LABEL, NewString(""));
}
return retVal;
}
ObjPtr DrawIconLabeledButtonObj(theButton, theButtonOwner)
ObjPtr theButton, theButtonOwner;
{
#ifdef GRAPHICS
int left, right, bottom, top;
int depth;
Bool hilight, active;
int icon;
int offset;
char *label;
char buttonLabel[128];
int value;
ObjPtr theColor;
int color;
int style;
FuncTyp extraDraw;
int diFlags;
if (!Get2DIntBounds(theButton, &left, &right, &bottom, &top))
{
return NULLOBJ;
}
if (IsDrawingRestricted(left, right, bottom, top))
{
return ObjFalse;
}
hilight = GetPredicate(theButton, HIGHLIGHTED);
value = GetPredicate(theButton, VALUE);
active = GetPredicate(theButton, ACTIVATED);
style = GetInt(GetIntVar("DrawIconLabeledButtonObj", theButton, STYLE));
if (GetVar(theButton, COLOR))
{
color = GetInt(GetIntVar("DrawIconLabeledButtonObj" ,theButton, COLOR));
}
else
{
color = UIGREEN;
}
if (GetVar(theButton, WHICHICON))
{
icon = GetInt(GetIntVar("DrawIconLabeledButtonObj",theButton, WHICHICON));
}
else
{
icon = ICONQUESTION;
}
if (GetVar(theButton, LABEL))
{
label = GetString(GetStringVar("DrawIconLabeledButtonObj",theButton, LABEL));
offset = ICONTEXTOFFSET / 2;
}
else
{
label = (char *) NIL;
offset = 0;
}
color = UIGREEN;
if (value)
{
if (GetVar(theButton, COLOR))
{
color = GetInt(GetIntVar("DrawIconButtonObj" ,theButton, COLOR));
}
/* if no COLOR, color remains UIGREEN */
}
else if (hilight)
{
color = UIHIBACKGROUND;
}
else
{
switch(style)
{
case BS_PLAIN:
color = UIBACKGROUND;
break;
case BS_PITTED:
color = UIICONBACK;
break;
default:
ReportError("DrawIconButtonObj", "Illegal STYLE");
}
}
diFlags = active ? DI_DRAWFORE | DI_DRAWBACK
: DI_DRAWFORE | DI_DRAWBACK | DI_GREY;
switch (style)
{
case BS_PLAIN:
diFlags = diFlags | DI_SMALLTEXT;
break;
case BS_PITTED:
break;
default:
ReportError("DrawIconLabelledButtonObj", "Illegal STYLE");
}
if (style == BS_PLAIN)
{
if (!active) BeginTranslucent();
DrawRaisedRect(left, right, bottom, top,
hilight ? UIHIBACKGROUND : UIBACKGROUND);
if (!active) EndTranslucent();
}
DrawIcon((left + right) / 2, (top + bottom) / 2 + offset,
icon, label, (char *) NIL, color, diFlags);
if (active)
{
extraDraw = GetMethod(theButton, ICONEXTRADRAW);
if (extraDraw)
{
(* extraDraw) (theButton, (int) ((left + right) / 2), (int) ((top + bottom) / 2) + offset);
}
}
return ObjTrue;
#endif /* GRAPHICS */
}
static ObjPtr SetButtonValuePretend(theButton, theValue)
ObjPtr theButton, theValue;
{
FuncTyp changer;
/* value is ignored, button just gets pressed */
InhibitLogging(true);
ChangedValue(theButton);
InhibitLogging(false);
ImInvalid(theButton);
if (logging) LogControl(theButton);
return ObjTrue;
}
static ObjPtr SetButtonValueReally(theButton, theValue)
ObjPtr theButton, theValue;
{
FuncTyp changer;
if (IsInt(theValue))
{
SetVar(theButton, VALUE, theValue);
}
else if (IsReal(theValue))
{
SetVar(theButton, VALUE, NewInt((int) GetReal(theValue)));
}
else
{
return ObjFalse;
}
InhibitLogging(true);
ChangedValue(theButton);
InhibitLogging(false);
ImInvalid(theButton);
if (logging) LogControl(theButton);
return ObjTrue;
}
#ifdef PROTO
Bool MakeButtonToggled(ObjPtr theButton, Bool flag)
#else
Bool MakeButtonToggled(theButton, flag)
ObjPtr theButton;
Bool flag;
#endif
{
if (flag)
{
return SetMethod(theButton, SETVAL, SetButtonValueReally);
}
else
{
return SetMethod(theButton, SETVAL, SetButtonValuePretend);
}
}
Bool ToggleButtonActivated(ObjPtr theButton)
{
SetVar(theButton, ACTIVATED, GetPredicate(theButton, ACTIVATED) ? ObjFalse : ObjTrue);
ImInvalid(theButton);
return true;
}
#ifdef PROTO
Bool ActivateButton(ObjPtr theButton, Bool flag)
#else
Bool ActivateButton(theButton, flag)
ObjPtr theButton;
Bool flag;
#endif
{
if (flag == GetPredicate(theButton, ACTIVATED))
{
return false;
}
SetVar(theButton, ACTIVATED, flag ? ObjTrue : ObjFalse);
ImInvalid(theButton);
return true;
}
/* SetRadioButtonGroupValue: Radio button group SETVAL method */
static ObjPtr SetRadioButtonGroupValue(theGroup, theValue)
ObjPtr theGroup, theValue;
{
ObjPtr buttonList; /* the Radio's list of buttons */
ThingListPtr runner; /* list runner */
int buttonNo; /* counts things as runner runs */
ObjPtr oneThing; /* one thing in the list */
int value; /* value of theValue */
if (IsInt(theValue))
{
value = GetInt(theValue);
}
else if (IsReal(theValue))
{
value = GetReal(theValue);
}
else
{
return ObjFalse;
}
SetVar(theGroup, VALUE, NewInt(value));
/* run down list of buttons and set all but one false. */
buttonList = GetListVar("SetRadioButtonGroupValue", theGroup, CONTENTS);
if (!buttonList)
{
return ObjFalse;
}
runner = LISTOF(buttonList);
buttonNo = 0;
/* find the button in the CONTENTS list */
while (runner && buttonNo < value)
{
runner = runner -> next;
++buttonNo;
}
if (!runner)
{
ReportError("SetRadioButtonGroupValue","tried to set to illegal value");
SetVar(theGroup, VALUE, NewInt(-1));
ChangedValue(theGroup);
ImInvalid(theGroup);
return ObjFalse;
}
oneThing = runner -> thing;
InhibitLogging(true);
ButtonPressed(oneThing);
ChangedValue(theGroup);
InhibitLogging(false);
if (logging) LogControl(theGroup);
ImInvalid(theGroup);
return ObjTrue;
}
ObjPtr NewButton(left, right, bottom, top, label)
int left, right, bottom, top;
char *label;
/*Makes a new panel with bounds left, right, bottom, top, and label label*/
{
ObjPtr retVal;
ObjPtr labelPtr;
ObjPtr hilightPtr;
retVal = NewObject(buttonClass, 0);
if(retVal)
{
labelPtr = NewString(label);
Set2DIntBounds(retVal, left, right, bottom, top);
hilightPtr = ObjFalse;
SetVar(retVal, NAME, labelPtr);
SetVar(retVal, HIGHLIGHTED, hilightPtr);
SetVar(retVal, VALUE, NewInt(0));
SetVar(retVal, ACTIVATED, ObjTrue);
return retVal;
}
else
{
return ObjFalse;
}
}
static ObjPtr DrawRadioButtonObj(theButton)
ObjPtr theButton;
{
#ifdef GRAPHICS
int left, right, bottom, top;
Bool hilight, active;
Bool value;
int marker;
char *label;
if (!Get2DIntBounds(theButton, &left, &right, &bottom, &top))
{
return NULLOBJ;
}
if (IsDrawingRestricted(left, right, bottom, top))
{
return ObjFalse;
}
hilight = GetPredicate(theButton, HIGHLIGHTED);
active = GetPredicate(theButton, ACTIVATED);
marker = GetInt(GetIntVar("DrawRadioButtonObj", theButton, MARKERTYPE));
label = GetString(GetStringVar("DrawRadioButtonObj",theButton, NAME));
value = GetPredicate(theButton, VALUE);
if (!active)
BeginTranslucent();
DrawRaisedRect(left, left + (top - bottom), bottom, top, hilight ? UIHIBACKGROUND : UIBACKGROUND);
if (value)
{
switch(marker)
{
case MARKERX:
DrawMarkerX(left+BUTTONDEPTH, left+(top-bottom) - BUTTONDEPTH,
bottom + BUTTONDEPTH, top - BUTTONDEPTH);
break;
case MARKERCHECK:
DrawMarkerCheck(left+BUTTONDEPTH, left+(top-bottom)-BUTTONDEPTH,
bottom + BUTTONDEPTH, top - BUTTONDEPTH);
break;
case MARKERBLOT:
DrawMarkerBlot(left+BUTTONDEPTH,left+(top-bottom)-BUTTONDEPTH,
bottom + BUTTONDEPTH, top - BUTTONDEPTH);
break;
case MARKERSPLAT:
DrawMarkerSplat(left+BUTTONDEPTH,left+(top-bottom)-BUTTONDEPTH,
bottom + BUTTONDEPTH, top - BUTTONDEPTH);
break;
}
}
if (!active)
EndTranslucent();
if (label)
{
if (active)
SetUIColor(UITEXT);
else
SetUIColor(UIGREYTEXT);
SetUIFont(BUTTONFONT);
DrawAString(LEFTALIGN, left + (top - bottom) + RADIOSPACER,
(top+bottom)/2 + LABELFONTFUDGE - (int) BUTTONFONTSIZE/2,
label);
}
#endif /* GRAPHICS */
}
#ifdef PROTO
static Bool TrackMouse(ObjPtr obj, int whichButton)
#else
static Bool TrackMouse(obj, whichButton)
ObjPtr obj;
int whichButton;
#endif
{
int mX, mY; /* track mouse coordinates */
Bool isDown; /* return value from Mouse, true if down */
int left, right, bottom, top; /* non-array version */
if (!Get2DIntBounds(obj, &left, &right, &bottom, &top))
{
return false;
}
/* the buggy version? */
while (Mouse(&mX, &mY))
{
if (mX < left || mX > right || mY < bottom || mY > top)
{
/* mouse outside rectangle */
if (GetPredicate(obj, HIGHLIGHTED))
{
SetVar(obj, HIGHLIGHTED, ObjFalse);/* turn highlight off */
DrawMe(obj); /* ..and redraw */
}
}
else
{
/* mouse inside rectangle */
if (!GetPredicate(obj, HIGHLIGHTED))
{
SetVar (obj, HIGHLIGHTED, ObjTrue);/* turn highlight on */
DrawMe(obj); /* ..and redraw */
}
}
}
/* always turn highlight off and redraw on exit */
SetVar(obj, HIGHLIGHTED, ObjFalse);
ImInvalid(obj);
/* is this obtuse or what? return true iff mouseup while in rectangle */
return !(mX < left || mX > right || mY < bottom || mY > top);
}
static ObjPtr ButtonPressedButton(theButton)
/* ButtonPressedButton: BUTTONPRESSED Method for vanilla buttons.
It only toggles the VALUE token of the button. returns true if
successful, false if not.
*/
ObjPtr theButton;
{
Bool value; /* value of it's VALUE int */
SetValue(theButton, GetPredicate(theButton, VALUE) ? NewInt(0) : NewInt(1));
return ObjTrue;
}
static ObjPtr ButtonPressedRadioButton(theButton)
ObjPtr theButton;
{
ObjPtr buttonList; /* the Radio's list of buttons */
ObjPtr parent; /* button's parent */
ThingListPtr runner; /* list runner */
ObjPtr oneThing; /* ont thing in the list */
int buttonNo;
/* run down list of buttons and set them all false. */
parent = GetVar(theButton, PARENT);
if (!parent)
{
ReportError("ButtonPressedRadioButton","Radio button has no PARENT!\n");
return ObjFalse;
}
buttonList = GetListVar("ButtonPressedRadioButton", parent, CONTENTS);
if (!buttonList)
{
return ObjFalse;
}
else
{
runner = LISTOF(buttonList);
SetVar(parent, VALUE, NewInt(-1));
buttonNo = 0;
while (runner)
{
ThingPtr oneThing;
oneThing = runner -> thing;
if (GetPredicate(oneThing, VALUE))
{
SetValue(oneThing, NewInt(false));
/* note there's a quirk here if old button = new button */
}
if (runner -> thing == theButton)
{
SetVar(parent, VALUE, NewInt(buttonNo));
}
++buttonNo;
runner = runner -> next;
}
}
SetValue(theButton, NewInt(true));
ChangedValue(parent);
return ObjTrue;
}
/* PressButton: button PRESS method. if mouse down in my rectangle, track
the mouse and (if up in my rectangle) change the value of the button.
returns true if mouse down in my rectangle, regardless of whether mouse
up happened in it.
*/
static ObjPtr PressButton(theButton, mouseX, mouseY, flags)
ObjPtr theButton;
int mouseX, mouseY;
long flags;
{
#ifdef INTERACTIVE
int left, right, bottom, top;
if (!Get2DIntBounds(theButton, &left, &right, &bottom, &top))
{
return ObjFalse;
}
/* test if mouse in my rectangle */
if (mouseX < left || mouseX > right ||
mouseY < bottom || mouseY > top)
{
/* mouse out of my rectangle, do nothing, return */
return ObjFalse;
}
if (TOOL(flags) == T_HELP)
{
ContextHelp(theButton);
return ObjTrue;
}
if (!GetPredicate(theButton, ACTIVATED))
{
return ObjFalse;
}
/* have to inhibit Undo saves for radio buttons. */
if (!inhibitSaveForUndo)
{
SaveForUndo(theButton);
}
MakeMeCurrent(theButton);
if (!TrackMouse(theButton, flags))
{
/* mouse up outside of this button, do nothing but draw me */
ImInvalid(theButton);
return ObjTrue; /*return true if mousedown in me,regardless of mouseup*/
}
ButtonPressed(theButton);
/* we hope that logging is handled in the SETVAL method! */
return ObjTrue;
#endif /* INTERACTIVE */
}
ObjPtr NewRadioButton(left, right, bottom, top, label)
int left, right, bottom, top;
char *label;
/*Makes a new panel with bounds left, right, bottom, top, and label label,
beloging to buttonGroup */
{
ObjPtr retVal;
ObjPtr labelPtr;
ObjPtr hilightPtr;
retVal = NewObject(radioButtonClass, 0);
if (retVal)
{
Set2DIntBounds(retVal, left, right, bottom, top);
labelPtr = NewString(label);
SetVar(retVal, NAME, labelPtr);
hilightPtr = ObjFalse;
SetVar(retVal, HIGHLIGHTED, hilightPtr);
SetVar(retVal, VALUE, NewInt(0));
SetVar(retVal, ACTIVATED, ObjTrue);
return retVal;
}
else
{
return ObjFalse;
}
}
/* Makes a new check box with bounds left, right, bottom, top, and label label*/
#ifdef PROTO
ObjPtr NewCheckBox(int left, int right, int bottom, int top, char *label,
Bool initValue)
#else
ObjPtr NewCheckBox(left, right, bottom, top, label, initValue)
int left, right, bottom, top;
Bool initValue;
char *label;
#endif
{
ObjPtr retVal;
ObjPtr labelPtr;
ObjPtr hilightPtr;
retVal = NewObject(checkBoxClass, 0);
if (retVal)
{
Set2DIntBounds(retVal, left, right, bottom, top);
labelPtr = NewString(label);
SetVar(retVal, NAME, labelPtr);
hilightPtr = ObjFalse;
SetVar(retVal, HIGHLIGHTED, hilightPtr);
SetVar(retVal, VALUE, initValue ? NewInt(1) : NewInt(0));
SetVar(retVal, ACTIVATED, ObjTrue);
return retVal;
}
else
{
return ObjFalse;
}
}
static ObjPtr ReshapeRadioButtonGroup(object, ol, or, ob, ot, left, right, bottom, top)
ObjPtr object;
int ol, or, ob, ot;
int left, right, bottom, top;
/*Reshapes object, which used to exist within owner with edges ol, or, ob, ot
to one which exists within owner with edges left, right, bottom, top.*/
{
ObjPtr boundsArray;
ObjPtr stickyInt;
real bounds[4];
real oldWidth, oldHeight; /*Old width and height*/
Bool sideLocked[4]; /*True iff side is locked*/
Bool xStretch, yStretch; /*Stretchiness in x and y*/
int stickiness; /*Side stickiness of the object*/
real oldBounds[4]; /*Old bounds of the object*/
ObjPtr contents; /*Contents of the object, if any*/
real wr, hr; /*Width and height ratios*/
wr = ((real) (right - left)) / ((real) (or - ol));
hr = ((real) (top - bottom)) / ((real) (ot - ob));
boundsArray = GetVar(object, BOUNDS);
if (!boundsArray || !IsArray(boundsArray) || RANK(boundsArray) != 1 ||
DIMS(boundsArray)[0] != 4)
{
return;
}
Array2CArray(bounds, boundsArray);
Array2CArray(oldBounds, boundsArray);
oldWidth = bounds[1] - bounds[0];
oldHeight = bounds[3] - bounds[2];
/*Get the object's stickiness*/
stickyInt = GetVar(object, STICKINESS);
if (stickyInt && IsInt(stickyInt))
{
stickiness = GetInt(stickyInt);
}
else
{
stickiness = 0;
}
if ((stickiness & STICKYLEFT) || (stickiness & FLOATINGLEFT))
{
if (stickiness & FLOATINGLEFT)
{
bounds[0] = (bounds[0] - ol) * wr + left;
}
else
{
bounds[0] += left - ol;
}
if (!((stickiness & STICKYRIGHT) || (stickiness & FLOATINGRIGHT)))
{
bounds[1] = bounds[0] + oldWidth;
}
}
if ((stickiness & STICKYRIGHT) || (stickiness & FLOATINGRIGHT))
{
if (stickiness & FLOATINGRIGHT)
{
bounds[1] = (bounds[1] - ol) * wr + left;
}
else
{
bounds[1] += right - or;
}
if (!((stickiness & STICKYLEFT) || (stickiness & FLOATINGLEFT)))
{
bounds[0] = bounds[1] - oldWidth;
}
}
if ((stickiness & STICKYBOTTOM) || (stickiness & FLOATINGBOTTOM))
{
if (stickiness & FLOATINGBOTTOM)
{
bounds[2] = (bounds[2] - ob) * hr + bottom;
}
else
{
bounds[2] += bottom - ob;
}
if (!((stickiness & STICKYTOP) || (stickiness & FLOATINGTOP)))
{
bounds[3] = bounds[2] + oldHeight;
}
}
if ((stickiness & STICKYTOP) || (stickiness & FLOATINGTOP))
{
if (stickiness & FLOATINGTOP)
{
bounds[3] = (bounds[3] - ob) * hr + bottom;
}
else
{
bounds[3] += top - ot;
}
if (!((stickiness & STICKYBOTTOM) || (stickiness & FLOATINGBOTTOM)))
{
bounds[2] = bounds[3] - oldHeight;
}
}
/*We've got a new bounds, put it back*/
boundsArray = NewRealArray(1, 4L);
CArray2Array(boundsArray, bounds);
SetVar(object, BOUNDS, boundsArray);
/*If there are some contents to this, do the reshape recursively*/
contents = GetVar(object, CONTENTS);
if (contents && IsList(contents))
{
ReshapeList(LISTOF(contents),
(int) oldBounds[0], (int) oldBounds[1] ,
(int) oldBounds[2], (int) oldBounds[3],
(int) bounds[0], (int) bounds[1],
(int) bounds[2], (int) bounds[3]);
}
}
static ObjPtr DrawRadioButtonGroup(theGroup)
ObjPtr theGroup;
{
#ifdef GRAPHICS
ObjPtr theList;
theList = GetListVar("DrawRadioButtonGroup", theGroup, CONTENTS);
if (!theList)
{
return NULLOBJ;
}
DrawList(theList);
return NULLOBJ;
#endif /* GRAPHICS */
}
static ObjPtr PressRadioButtonGroup(theGroup, mX, mY, flags)
ObjPtr theGroup;
int mX, mY;
long flags;
{
#ifdef INTERACTIVE
int left, right, bottom, top;
ObjPtr theList;
ObjPtr valuePtr; /* radio group value ptr */
int oldValue; /* group's old value */
FuncTyp bpmethod; /* BUTTONPRESSED method */
ObjPtr pressVal; /* thing returned by PressList */
theList = GetListVar("PressRadioButtonGroup", theGroup, CONTENTS);
if (!theList)
{
return ObjFalse;
}
if (!Get2DIntBounds(theGroup, &left, &right, &bottom, &top))
{
return ObjFalse;
}
valuePtr = GetIntVar("PressRadioButtonGroup", theGroup, VALUE);
if (!valuePtr)
{
return ObjFalse;
}
oldValue = GetInt(valuePtr);
/* test if mouse in my rectangle */
if (mX < left || mX > right ||
mY < bottom || mY > top)
{
/* mouse out of my rectangle, do nothing, return */
return ObjFalse;
}
SaveForUndo(theGroup);
inhibitSaveForUndo = true;
pressVal = PressList(theList, mX, mY, flags);
inhibitSaveForUndo = false;
if(IsTrue(pressVal))
{
/* if really changed */
if (oldValue != GetInt(GetIntVar("PressRadioButtonGroup",theGroup, VALUE)))
{
InhibitLogging(true);
ButtonPressed(theGroup);
InhibitLogging(false);
}
if (logging) LogControl(theGroup);
return ObjTrue;
}
else
{
if (TOOL(flags) == T_HELP)
{
/* it was a help-press in the group bounds (that missed buttons) */
ContextHelp(theGroup);
return ObjTrue;
}
else
{
return ObjFalse;
}
}
#endif /* INTERACTIVE */
}
ObjPtr NewRadioButtonGroup(name)
char *name;
/* creates an empty radio button group */
{
ObjPtr retVal;
retVal = NewObject(radioGroupClass, 0);
if (retVal)
{
SetVar(retVal, CONTENTS, NewList());
SetVar(retVal, VALUE, NewInt(-1));
SetVar(retVal, NAME, NewString(name));
SetVar(retVal, ACTIVATED, ObjTrue);
return retVal;
}
else
{
return ObjFalse;
}
}
void AddRadioButton(theGroup, theButton)
ObjPtr theGroup, theButton;
/* adds a radio button object to an existing radio button group */
{
ObjPtr groupBoundsArray;
int bounds[4], groupBounds[4];
ObjPtr theList;
int i; /* temporary? loop counter */
if (!Get2DIntBounds(theButton,&bounds[0],&bounds[1],&bounds[2],&bounds[3]))
{
return;
}
theList = GetListVar("AddRadioButton", theGroup, CONTENTS);
if(!theList)
{
return;
}
groupBoundsArray = GetVar(theGroup, BOUNDS);
if(!groupBoundsArray)
{
/*Try to make bounds. Initial value is bounds of first button*/
Set2DIntBounds(theGroup, bounds[0], bounds[1], bounds[2], bounds[3]);
}
else
{
Get2DIntBounds(theGroup, &groupBounds[0], &groupBounds[1],
&groupBounds[2], &groupBounds[3]);
/* if necessary, modify the BOUNDS of the button group to include
the new button
*/
groupBounds[0] = bounds[0]<groupBounds[0] ? bounds[0] : groupBounds[0];
groupBounds[1] = bounds[1]>groupBounds[1] ? bounds[1] : groupBounds[1];
groupBounds[2] = bounds[2]<groupBounds[2] ? bounds[2] : groupBounds[2];
groupBounds[3] = bounds[3]>groupBounds[3] ? bounds[3] : groupBounds[3];
Set2DIntBounds(theGroup, groupBounds[0], groupBounds[1],
groupBounds[2], groupBounds[3]);
}
PostfixList(theList, theButton);
SetVar(theButton, PARENT, theGroup);
SetMethod(theButton, BUTTONPRESSED, ButtonPressedRadioButton);
SetMethod(theButton, SETVAL, SetButtonValueReally);
/*EMP don't log individual buttons, only groups*/
SetVar(theButton, INHIBITLOGGING, ObjTrue);
}
void InitButtons()
/* sets up button stuff */
{
buttonClass = NewObject(controlClass, 0);
AddToReferenceList(buttonClass);
SetMethod(buttonClass, DRAW, DrawButtonObj);
SetMethod(buttonClass, PRESS, PressButton);
SetMethod(buttonClass, BUTTONPRESSED, ButtonPressedButton);
SetMethod(buttonClass, SETVAL, SetButtonValuePretend);
SetVar(buttonClass, TYPESTRING, NewString("button"));
SetVar(buttonClass, HELPSTRING, NewString(
"To press the button, click on it with the left mouse button. If you move the \
mouse away from the button before releasing, the button will not be pressed."));
iconButtonClass = NewObject(buttonClass, 0);
AddToReferenceList(iconButtonClass);
SetMethod(iconButtonClass, DRAW, DrawIconButtonObj);
SetMethod(iconButtonClass, SETVAL, SetButtonValuePretend);
SetVar(iconButtonClass, TYPESTRING, NewString("icon button"));
iconLabeledButtonClass = NewObject(iconButtonClass, 0);
AddToReferenceList(iconLabeledButtonClass);
SetMethod(iconLabeledButtonClass, DRAW, DrawIconLabeledButtonObj);
SetVar(iconLabeledButtonClass,TYPESTRING,NewString("icon button"));
radioGroupClass = NewObject(controlClass, 0);
AddToReferenceList(radioGroupClass);
SetMethod(radioGroupClass, DRAW, DrawRadioButtonGroup);
SetMethod(radioGroupClass, PRESS, PressRadioButtonGroup);
SetMethod(radioGroupClass, SETVAL, SetRadioButtonGroupValue);
SetMethod(radioGroupClass, RESHAPE, ReshapeRadioButtonGroup);
SetVar(radioGroupClass, TYPESTRING, NewString("radio button group"));
SetVar(radioGroupClass, HELPSTRING, NewString(
"A radio button group provides a way to select one choice from among several. \
Selecting one of the buttons automatically deselects the others in the group."));
radioButtonClass = NewObject(buttonClass, 0);
AddToReferenceList(radioButtonClass);
SetMethod(radioButtonClass, DRAW, DrawRadioButtonObj);
SetVar(radioButtonClass, MARKERTYPE, NewInt(MARKERSPLAT));
SetVar(radioButtonClass, TYPESTRING, NewString("radio button"));
oldRadioButtonClass = NewObject(radioButtonClass, 0);
AddToReferenceList(oldRadioButtonClass);
SetVar(oldRadioButtonClass, MARKERTYPE, NewInt(MARKERX));
checkBoxClass = NewObject(buttonClass, 0);
AddToReferenceList(checkBoxClass);
SetMethod(checkBoxClass, DRAW, DrawRadioButtonObj);
SetMethod(checkBoxClass, SETVAL, SetButtonValueReally);
SetVar(checkBoxClass, MARKERTYPE, NewInt(MARKERCHECK));
SetVar(checkBoxClass, TYPESTRING, NewString("check box"));
}
void KillButtons()
/* kills button stuff */
{
DeleteThing(checkBoxClass);
DeleteThing(radioButtonClass);
DeleteThing(radioGroupClass);
DeleteThing(iconButtonClass);
DeleteThing(buttonClass);
}